import { EventEmitter } from 'events';
import { nanoid } from 'nanoid/non-secure';

import {
  ChatMessage,
  ChatResponse,
  StreamingResponse,
  ChatMode
} from './types';

// 抽象接口定义
export interface MessageProcessor {
  processMessage(message: ChatMessage, options: any): Promise<ChatResponse>;
  processStreamingMessage(message: ChatMessage, options: any): AsyncIterable<StreamingResponse>;
}

export interface ToolExecutor {
  executeToolUse(toolName: string, input: any, options: any): Promise<any>;
}

export interface MemoryOperator {
  handleMemoryOperation(operation: string, data: any, options: any): Promise<any>;
}

/**
 * 消息代理
 * 负责处理消息传递和流式响应
 */
export class MessageBroker extends EventEmitter {
  private activeStreams = new Map<string, AbortController>();
  private messageQueue: ChatMessage[] = [];

  constructor(
    private messageProcessor: MessageProcessor,
    private toolExecutor: ToolExecutor,
    private memoryOperator: MemoryOperator
  ) {
    super();
  }

  /**
   * 发送消息
   */
  async sendMessage(
    message: ChatMessage,
    options: {
      streaming?: boolean;
      mode?: ChatMode;
      abortSignal?: AbortSignal;
    } = {}
  ): Promise<ChatResponse | AsyncIterable<StreamingResponse>> {
    const messageId = this.generateMessageId();
    message.id = messageId;

    // 添加到队列
    this.messageQueue.push(message);

    // 创建中止控制器
    const abortController = new AbortController();
    this.activeStreams.set(messageId, abortController);

    // 监听外部中止信号
    if (options.abortSignal) {
      options.abortSignal.addEventListener('abort', () => {
        this.cancelMessage(messageId);
      });
    }

    try {
      if (options.streaming) {
        return this.processStreamingMessage(message, options);
      } else {
        return await this.processMessage(message, options);
      }
    } catch (error) {
      this.activeStreams.delete(messageId);
      throw error;
    }
  }

  /**
   * 处理流式消息
   */
  private async *processStreamingMessage(
    message: ChatMessage,
    options: any
  ): AsyncIterable<StreamingResponse> {
    const messageId = message.id!;

    try {
      // 发出消息开始事件
      this.emit('messageStart', { messageId, message });

      // 使用注入的消息处理器
      yield* this.messageProcessor.processStreamingMessage(message, options);

      // 发出消息完成事件
      this.emit('messageComplete', { messageId });
    } catch (error) {
      // 发出错误事件
      this.emit('messageError', { messageId, error });
      throw error;
    } finally {
      this.activeStreams.delete(messageId);
    }
  }

  /**
   * 处理非流式消息
   */
  private async processMessage(
    message: ChatMessage,
    options: any
  ): Promise<ChatResponse> {
    const messageId = message.id!;

    try {
      // 发出消息开始事件
      this.emit('messageStart', { messageId, message });

      // 使用注入的消息处理器
      const response = await this.messageProcessor.processMessage(message, options);

      // 发出消息完成事件
      this.emit('messageComplete', { messageId, response });

      return response;
    } catch (error) {
      // 发出错误事件
      this.emit('messageError', { messageId, error });
      throw error;
    } finally {
      this.activeStreams.delete(messageId);
    }
  }



  /**
   * 取消消息
   */
  cancelMessage(messageId: string): boolean {
    const abortController = this.activeStreams.get(messageId);
    if (abortController) {
      abortController.abort();
      this.activeStreams.delete(messageId);

      this.emit('messageCancelled', { messageId });
      return true;
    }
    return false;
  }

  /**
   * 取消所有活动消息
   */
  cancelAllMessages(): void {
    for (const [messageId, abortController] of this.activeStreams.entries()) {
      abortController.abort();
      this.emit('messageCancelled', { messageId });
    }
    this.activeStreams.clear();
  }

  /**
   * 获取活动流数量
   */
  getActiveStreamCount(): number {
    return this.activeStreams.size;
  }

  /**
   * 检查消息是否活动
   */
  isMessageActive(messageId: string): boolean {
    return this.activeStreams.has(messageId);
  }

  /**
   * 获取队列中的消息数量
   */
  getQueueLength(): number {
    return this.messageQueue.length;
  }

  /**
   * 清空消息队列
   */
  clearQueue(): void {
    this.messageQueue = [];
  }

  /**
   * 处理工具使用
   */
  async handleToolUse(
    toolName: string,
    input: any,
    options: {
      messageId?: string;
      allowExecution?: boolean;
    } = {}
  ): Promise<any> {
    const messageId = options.messageId || this.generateMessageId();

    // 发出工具使用开始事件
    this.emit('toolUseStart', {
      messageId,
      toolName,
      input
    });

    try {
      // 使用注入的工具执行器
      const result = await this.toolExecutor.executeToolUse(toolName, input, options);

      // 发出工具使用完成事件
      this.emit('toolUseComplete', {
        messageId,
        toolName,
        input,
        result
      });

      return result;
    } catch (error) {
      // 发出工具使用错误事件
      this.emit('toolUseError', {
        messageId,
        toolName,
        input,
        error
      });
      throw error;
    }
  }

  /**
   * 处理记忆操作
   */
  async handleMemoryOperation(
    operation: 'save' | 'retrieve' | 'update' | 'delete',
    data: any,
    options: {
      messageId?: string;
    } = {}
  ): Promise<any> {
    const messageId = options.messageId || this.generateMessageId();

    // 发出记忆操作事件
    this.emit('memoryOperation', {
      messageId,
      operation,
      data
    });

    // 使用注入的记忆操作器
    return await this.memoryOperator.handleMemoryOperation(operation, data, options);
  }

  /**
   * 生成消息ID
   */
  private generateMessageId(): string {
    return nanoid();
  }



  /**
   * 清理资源
   */
  dispose(): void {
    this.cancelAllMessages();
    this.clearQueue();
    this.removeAllListeners();
  }
}
